org.kairosdb.util.Util.java Source code

Java tutorial

Introduction

Here is the source code for org.kairosdb.util.Util.java

Source

/*
 * Copyright 2013 Proofpoint Inc.
 *
 *    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.kairosdb.util;

import com.google.common.collect.ImmutableList;
import org.joda.time.DateTime;
import org.joda.time.DateTimeZone;
import org.kairosdb.core.datastore.Sampling;

import java.io.*;
import java.net.*;
import java.util.Collections;
import java.util.List;

import static com.google.common.base.Preconditions.checkNotNull;

public class Util {
    /**
     Special thanks to Nadeau software consulting for publishing this code.
     http://nadeausoftware.com/node/97
     @param s string representation of number to parse
     @return number
     */
    public static long parseLong(final CharSequence s) {
        if (s == null)
            throw new NumberFormatException("Null string");

        // Check for a sign.
        long num = 0;
        long sign = -1;
        final int len = s.length();
        final char ch = s.charAt(0);
        if (ch == '-') {
            if (len == 1)
                throw new NumberFormatException("Missing digits:  " + s);
            sign = 1;
        } else {
            final int d = ch - '0';
            if (d < 0 || d > 9)
                throw new NumberFormatException("Malformed:  " + s);
            num = -d;
        }

        // Build the number.
        final long max = (sign == -1L) ? -Long.MAX_VALUE : Long.MIN_VALUE;
        final long multmax = max / 10;
        int i = 1;
        while (i < len) {
            long d = s.charAt(i++) - '0';
            if (d < 0L || d > 9L)
                throw new NumberFormatException("Malformed:  " + s);
            if (num < multmax)
                throw new NumberFormatException("Over/underflow:  " + s);
            num *= 10;
            if (num < (max + d))
                throw new NumberFormatException("Over/underflow:  " + s);
            num -= d;
        }

        return sign * num;
    }

    /**
     * Returns the host name. First tries to execute "hostname" on the machine. This should work for Linux, Windows,
     * and Mac. If, for some reason hostname fails, then get the name from InetAddress (which might change depending
     * on network setup)
     *
     * @return hostname
     */
    public static String getHostName() {
        try {
            Runtime run = Runtime.getRuntime();
            Process process = run.exec("hostname");
            InputStreamReader isr = new InputStreamReader(process.getInputStream());
            BufferedReader br = new BufferedReader(isr);

            // Need to read all lines from the stream or the process could hang
            StringBuilder buffer = new StringBuilder();
            String line;
            while ((line = br.readLine()) != null)
                buffer.append(line);

            int returnValue = process.waitFor();
            if (returnValue == 0)
                return buffer.toString();
        } catch (Exception e) {
            // ignore
        }

        try {
            return InetAddress.getLocalHost().getHostName();
        } catch (UnknownHostException e) {
            return "";
        }
    }

    public static void packUnsignedLong(long value, DataOutput buffer) throws IOException {
        /* Encodes a value using the variable-length encoding from
        <a href="http://code.google.com/apis/protocolbuffers/docs/encoding.html">
        Google Protocol Buffers</a>. Zig-zag is not used, so input must not be negative.
        If values can be negative, use {@link #writeSignedVarLong(long, DataOutput)}
        instead. This method treats negative input as like a large unsigned value. */
        while ((value & ~0x7FL) != 0L) {
            buffer.writeByte((int) ((value & 0x7F) | 0x80));
            value >>>= 7;
        }
        buffer.writeByte((int) value);
    }

    public static long unpackUnsignedLong(DataInput buffer) throws IOException {
        int shift = 0;
        long result = 0;
        while (shift < 64) {
            final byte b = buffer.readByte();
            result |= (long) (b & 0x7F) << shift;
            if ((b & 0x80) == 0) {
                return result;
            }
            shift += 7;
        }
        throw new IllegalArgumentException("Variable length quantity is too long");
    }

    public static void packLong(long value, DataOutput buffer) throws IOException {
        // Great trick from http://code.google.com/apis/protocolbuffers/docs/encoding.html#types
        packUnsignedLong((value << 1) ^ (value >> 63), buffer);

    }

    public static long unpackLong(DataInput buffer) throws IOException {
        long value = unpackUnsignedLong(buffer);

        return ((value >>> 1) ^ -(value & 1));
    }

    public static InetAddress findPublicIp() {
        // Check if local host address is a good v4 address
        InetAddress localAddress = null;
        try {
            localAddress = InetAddress.getLocalHost();
            if (isGoodV4Address(localAddress)) {
                return localAddress;
            }
        } catch (UnknownHostException ignored) {
        }
        if (localAddress == null) {
            try {
                localAddress = InetAddress.getByAddress(new byte[] { 127, 0, 0, 1 });
            } catch (UnknownHostException e) {
                throw new AssertionError("Could not get local ip address");
            }
        }

        // check all up network interfaces for a good v4 address
        for (NetworkInterface networkInterface : getGoodNetworkInterfaces()) {
            for (InetAddress address : Collections.list(networkInterface.getInetAddresses())) {
                if (isGoodV4Address(address)) {
                    return address;
                }
            }
        }
        // check all up network interfaces for a good v6 address
        for (NetworkInterface networkInterface : getGoodNetworkInterfaces()) {
            for (InetAddress address : Collections.list(networkInterface.getInetAddresses())) {
                if (isGoodV6Address(address)) {
                    return address;
                }
            }
        }
        // just return the local host address
        // it is most likely that this is a disconnected developer machine
        return localAddress;
    }

    /**
     Returns true if the string contains a number. This means it contains only digits, the minus sign, plus sign
     and a period.
        
     @param s string to test
     @return true if only contains a number value
     */
    public static boolean isNumber(String s) {
        checkNotNull(s);

        if (s.isEmpty())
            return false;

        int start = 0;
        char firstChar = s.charAt(0);
        if (firstChar == '+' || firstChar == '-' || firstChar == '.') {
            start = 1;
            if (s.length() == 1)
                return false;
        }

        for (int i = start; i < s.length(); i++) {
            char c = s.charAt(i);
            if (!Character.isDigit(c) && c != '.')
                return false;
        }

        //noinspection RedundantIfStatement
        if (s.charAt(s.length() - 1) == '.')
            return false; // can't have trailing period

        return true;
    }

    private static List<NetworkInterface> getGoodNetworkInterfaces() {
        ImmutableList.Builder<NetworkInterface> builder = ImmutableList.builder();
        try {
            for (NetworkInterface networkInterface : Collections.list(NetworkInterface.getNetworkInterfaces())) {
                try {
                    if (!networkInterface.isLoopback() && networkInterface.isUp()) {
                        builder.add(networkInterface);
                    }
                } catch (Exception ignored) {
                }
            }
        } catch (SocketException ignored) {
        }
        return builder.build();
    }

    private static boolean isGoodV4Address(InetAddress address) {
        return address instanceof Inet4Address && !address.isAnyLocalAddress() && !address.isLoopbackAddress()
                && !address.isMulticastAddress();
    }

    private static boolean isGoodV6Address(InetAddress address) {
        return address instanceof Inet6Address && !address.isAnyLocalAddress() && !address.isLoopbackAddress()
                && !address.isMulticastAddress();
    }

    /**
     Computes the duration of the sampling (value * unit) starting at timestamp.
        
     @param timestamp unix timestamp of the start time.
     @return the duration of the sampling in millisecond.
     */
    public static long getSamplingDuration(long timestamp, Sampling sampling, DateTimeZone timeZone) {
        long ret = sampling.getValue();
        DateTime dt = new DateTime(timestamp, timeZone);
        switch (sampling.getUnit()) {
        case YEARS:
            ret = new org.joda.time.Duration(dt, dt.plusYears((int) sampling.getValue())).getMillis();
            break;
        case MONTHS:
            ret = new org.joda.time.Duration(dt, dt.plusMonths((int) sampling.getValue())).getMillis();
            break;
        case WEEKS:
            ret = new org.joda.time.Duration(dt, dt.plusWeeks((int) sampling.getValue())).getMillis();
            break;
        case DAYS:
            ret = new org.joda.time.Duration(dt, dt.plusDays((int) sampling.getValue())).getMillis();
            break;
        case HOURS:
            ret = new org.joda.time.Duration(dt, dt.plusHours((int) sampling.getValue())).getMillis();
            break;
        case MINUTES:
            ret = new org.joda.time.Duration(dt, dt.plusMinutes((int) sampling.getValue())).getMillis();
            break;
        case SECONDS:
            ret = new org.joda.time.Duration(dt, dt.plusSeconds((int) sampling.getValue())).getMillis();
            break;
        case MILLISECONDS:
            ret = (long) sampling.getValue();
            break;
        }
        return ret;
    }
}