<commit_before>package com.splicemachine.derby.hbase;

import javax.management.InstanceAlreadyExistsException;
import javax.management.MBeanRegistrationException;
import javax.management.MBeanServer;
import javax.management.MXBean;
import javax.management.MalformedObjectNameException;
import javax.management.NotCompliantMBeanException;
import javax.management.ObjectName;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import java.util.jar.JarFile;
import java.util.jar.Manifest;

import org.apache.log4j.Logger;

import com.splicemachine.hbase.jmx.JMXUtils;
import com.splicemachine.utils.SpliceLogUtils;

/**
 * Class that reads Splice build info from splice_machine-*.jar MANIFEST and registers with JMX.<br/>
 * Supports finding Splice build info from JMX and Splice Admin procedure.
 *
 * @author <NAME>
 *         Date: 5/27/14
 */
public class ManifestReader {
    private static final Logger LOG = Logger.getLogger(ManifestReader.class);

    /**
     * Register with JMX
     * @param mbs Managed Bean Server
     * @throws MalformedObjectNameException
     * @throws NotCompliantMBeanException
     * @throws InstanceAlreadyExistsException
     * @throws MBeanRegistrationException
     */
    public void registerJMX(MBeanServer mbs) throws MalformedObjectNameException,
        NotCompliantMBeanException,
        InstanceAlreadyExistsException,
        MBeanRegistrationException {
        ObjectName name = new ObjectName(JMXUtils.SPLICEMACHINE_VERSION);
        mbs.registerMBean(new SpliceMachineVersionImpl(readManifestOnClasspath()),name);
    }

    /**
     * Interface to expose to JMX for version info
     */
    @MXBean
    public interface SpliceMachineVersion {
        /** @return the Splice release version */
        String getRelease();
        /** @return the Git commit that was used to build this version */
        String getImplementationVersion();
        /** @return the date/time of the build */
        String getBuildTime();
        /** @return the Splice Machine URL */
        String getURL();
        /** @return the Splice major release version */
        int getMajorVersionNumber();
        /** @return the Splice minor release version */
        int getMinorVersionNumber();
        /** @return the Splice patch number */
        int getPatchVersionNumber();
    }

    /**
     * Class that implements interface exposed to JMX
     */
    public static class SpliceMachineVersionImpl implements SpliceMachineVersion {
        private final Map<String,String> versionInfo;

        public SpliceMachineVersionImpl(Map<String,String> manifestProps) {
            if (manifestProps == null) {
                SpliceLogUtils.warn(LOG, "Unable to register Splice Machine Version JMX entry. Version information " +
                    "will be unavailable.");
            }
            this.versionInfo = manifestProps;
        }

        @Override
        public String getRelease() {return (this.versionInfo == null ? "Unknown" : this.versionInfo.get("Release"));}

        @Override
        public String getImplementationVersion() {return (this.versionInfo == null ? "Unknown" : this.versionInfo.get("Implementation-Version"));}

        @Override
        public String getBuildTime() {return (this.versionInfo == null ? "Unknown" : this.versionInfo.get("Build-Time"));}

        @Override
        public String getURL() {return (this.versionInfo == null ? "Unknown" : this.versionInfo.get("URL"));}

        @Override
        public String toString() {
            return "Release " + getRelease() + '\n' + "ImplementationVersion " + getImplementationVersion() + '\n' +
                "BuildTime " + getBuildTime() + '\n' + "URL " + getURL() + '\n';
        }

        @Override
        public int getMajorVersionNumber() {
            String release = getRelease();

            if (release == null) {
                return -1;
            }
            String[] s = splitReleaseString(release);

            return (new Integer(s[0])).intValue();
        }

        @Override
        public int getMinorVersionNumber() {
            String release = getRelease();

            if (release == null) {
                return -1;
            }
            String[] s = splitReleaseString(release);

            return (new Integer(s[1])).intValue();
        }

        @Override
        public int getPatchVersionNumber() {
            String release = getRelease();

            if (release == null) {
                return -1;
            }
            String[] s = splitReleaseString(release);
            if (s[2] == null)
                return 0;
            return (new Integer(s[2])).intValue();
        }

        private String[] splitReleaseString(String release) {
            String[] s = release.split("\\.");
            int count = 0;
            while(Character.isDigit(s[2].charAt(count))) {
                count++;
            }
            if (count == 0)
                s[2] = null;
            else
                s[2] = s[2].substring(0, count);

            return s;
        }
    }

    /**
     * Read the manifest from the splice_machine-*.jar<commit_msg>Making ManifestReader handle malformed or absent version information gracefully<commit_after>package com.splicemachine.derby.hbase;

import javax.management.InstanceAlreadyExistsException;
import javax.management.MBeanRegistrationException;
import javax.management.MBeanServer;
import javax.management.MXBean;
import javax.management.MalformedObjectNameException;
import javax.management.NotCompliantMBeanException;
import javax.management.ObjectName;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import java.util.jar.JarFile;
import java.util.jar.Manifest;

import org.apache.log4j.Logger;

import com.splicemachine.hbase.jmx.JMXUtils;
import com.splicemachine.utils.SpliceLogUtils;

/**
 * Class that reads Splice build info from splice_machine-*.jar MANIFEST and registers with JMX.<br/>
 * Supports finding Splice build info from JMX and Splice Admin procedure.
 *
 * @author <NAME>
 *         Date: 5/27/14
 */
public class ManifestReader {
    private static final Logger LOG = Logger.getLogger(ManifestReader.class);

    /**
     * Register with JMX
     * @param mbs Managed Bean Server
     * @throws MalformedObjectNameException
     * @throws NotCompliantMBeanException
     * @throws InstanceAlreadyExistsException
     * @throws MBeanRegistrationException
     */
    public void registerJMX(MBeanServer mbs) throws MalformedObjectNameException,
        NotCompliantMBeanException,
        InstanceAlreadyExistsException,
        MBeanRegistrationException {
        ObjectName name = new ObjectName(JMXUtils.SPLICEMACHINE_VERSION);
        mbs.registerMBean(new SpliceMachineVersionImpl(readManifestOnClasspath()),name);
    }

    /**
     * Interface to expose to JMX for version info
     */
    @MXBean
    public interface SpliceMachineVersion {
        /** @return the Splice release version */
        String getRelease();
        /** @return the Git commit that was used to build this version */
        String getImplementationVersion();
        /** @return the date/time of the build */
        String getBuildTime();
        /** @return the Splice Machine URL */
        String getURL();
        /** @return the Splice major release version */
        int getMajorVersionNumber();
        /** @return the Splice minor release version */
        int getMinorVersionNumber();
        /** @return the Splice patch number */
        int getPatchVersionNumber();
    }

    /**
     * Class that implements interface exposed to JMX
     */
    public static class SpliceMachineVersionImpl implements SpliceMachineVersion {
        private final Map<String,String> versionInfo;

        public SpliceMachineVersionImpl(Map<String,String> manifestProps) {
            if (manifestProps == null) {
                SpliceLogUtils.warn(LOG, "Unable to register Splice Machine Version JMX entry. Version information " +
                    "will be unavailable.");
            }
            this.versionInfo = manifestProps;
        }

        @Override
        public String getRelease() {return (this.versionInfo == null ? "Unknown" : this.versionInfo.get("Release"));}

        @Override
        public String getImplementationVersion() {return (this.versionInfo == null ? "Unknown" : this.versionInfo.get("Implementation-Version"));}

        @Override
        public String getBuildTime() {return (this.versionInfo == null ? "Unknown" : this.versionInfo.get("Build-Time"));}

        @Override
        public String getURL() {return (this.versionInfo == null ? "Unknown" : this.versionInfo.get("URL"));}

        @Override
        public String toString() {
            return "Release " + getRelease() + '\n' + "ImplementationVersion " + getImplementationVersion() + '\n' +
                "BuildTime " + getBuildTime() + '\n' + "URL " + getURL() + '\n';
        }

        @Override
        public int getMajorVersionNumber() {
            String release = getRelease();

            if (release == null|| release.length()<=0) {
                return -1;
            }
            String[] s = splitReleaseString(release);
            if(s.length<=0) return -1;

            try {
                return Integer.parseInt(s[0]);
            }catch(NumberFormatException nfe){ return -1;}
        }

        @Override
        public int getMinorVersionNumber() {
            String release = getRelease();

            if (release == null|| release.length()<=0) {
                return -1;
            }
            String[] s = splitReleaseString(release);

            if(s.length<1) return -1;
            try {
                return Integer.parseInt(s[1]);
            }catch(NumberFormatException nfe){ return -1;}
        }

        @Override
        public int getPatchVersionNumber() {
            String release = getRelease();

            if (release == null|| release.length()<=0) {
                return -1;
            }
            String[] s = splitReleaseString(release);
            if (s.length<2 ||s[2] == null)
                return 0;

            try {
                return Integer.parseInt(s[2]);
            }catch(NumberFormatException nfe){ return -1;}
        }

        private String[] splitReleaseString(String release) {
            String[] s = release.split("\\.");
            if(s.length<2){
                return s;
            }
            int count = 0;
            while(Character.isDigit(s[2].charAt(count))) {
                count++;
            }
            if (count == 0)
                s[2] = null;
            else
                s[2] = s[2].substring(0, count);

            return s;
        }
    }

    /**
     * Read the manifest from the splice_machine-*.jar
{'fraction_non_alphanumeric': 0.10445454545454545, 'fraction_numerical': 0.004909090909090909, 'mean_word_length': 2.2907568052647322, 'pattern_counts': {'":': 0, '<': 18, '<?xml version=': 0, '>': 11, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4444594', 'n_tokens_mistral': 2947, 'n_tokens_neox': 2821, 'n_words': 744}