<commit_before>/*
 * Copyright (C) 2012 - present by <NAME>.
 * Please see distribution for license.
 */
package com.assylias.jbloomberg;

import com.bloomberglp.blpapi.Datetime;
import com.bloomberglp.blpapi.Element;
import com.bloomberglp.blpapi.ElementIterator;
import com.bloomberglp.blpapi.Schema;
import java.io.BufferedReader;
import java.io.File;
import java.io.InputStreamReader;
import java.nio.charset.Charset;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * A utility class that should not be very useful for the users of the API.
 */
final class BloombergUtils {

    private final static Logger logger = LoggerFactory.getLogger(BloombergUtils.class);
    private static volatile boolean isBbcommStarted = false;
    private final static String BBCOMM_PROCESS = "bbcomm.exe";
    private final static String BBCOMM_FOLDER = "C:/blp/API";

    private BloombergUtils() {
    }

    /**
     * Transforms a Bloomberg Element into the most specific Object (for example: Double, Float, Integer, DateTime,
     * String etc.).<br>
     * Complex types are returned in the form of collections ({@code List<Object>} for arrays and
     * {@code Map<String, Object>}
     * for sequences).
     */
    public static Object getSpecificObjectOf(Element field) {
        if (field.datatype() == Schema.Datatype.FLOAT64) {
            //likeliest data type
            return field.getValueAsFloat64();
        } else if (field.datatype() == Schema.Datatype.FLOAT32) {
            return field.getValueAsFloat32();
        } else if (field.datatype() == Schema.Datatype.BOOL) {
            return field.getValueAsBool();
        } else if (field.datatype() == Schema.Datatype.CHAR) {
            return field.getValueAsChar();
        } else if (field.datatype() == Schema.Datatype.INT32) {
            return field.getValueAsInt32();
        } else if (field.datatype() == Schema.Datatype.INT64) {
            return field.getValueAsInt64();
        } else if (field.datatype() == Schema.Datatype.STRING) {
            return field.getValueAsString();
        } else if (field.datatype() == Schema.Datatype.DATE
                || field.datatype() == Schema.Datatype.DATETIME
                || field.datatype() == Schema.Datatype.TIME) {
            Calendar dt = field.getValueAsDate().calendar(); //returns a calendar with TZ = UTC
            return LocalDateTime.ofInstant(dt.toInstant(), ZoneId.of("Z"));
        } else if (field.isArray()) {
            List<Object> list = new ArrayList<>(field.numValues());
            for (int i = 0; i < field.numValues(); i++) {
                list.add(getSpecificObjectOf(field.getValueAsElement(i)));
            }
            return list;
        } else if (field.datatype() == Schema.Datatype.SEQUENCE
                || field.datatype() == Schema.Datatype.CHOICE) { //has to be after array because arrays are sequences...
            ElementIterator it = field.elementIterator();
            Map<String, Object> map = new LinkedHashMap<>(field.numElements(), 1.0f);
            while (it.hasNext()) {
                Element e = it.next();
                map.put(e.name().toString(), getSpecificObjectOf(e));
            }
            return map;
        } else {
            return field.toString(); //always works
        }
    }

    /**
     * Starts the bbcomm process if necessary, which is required to connect to the Bloomberg data feed.<br>
     * This method will block up to one second if it needs to manually start the process. If the process is not
     * started by the end of the timeout, this method will return false but the process might start later on.
     * <p/>
     * @return true if bbcomm was started successfully within one second, false otherwise.
     */
    public static boolean startBloombergProcessIfNecessary() {<commit_msg>Fix time zone issues and return data LocalDate when there is no time information<commit_after>/*
 * Copyright (C) 2012 - present by <NAME>.
 * Please see distribution for license.
 */
package com.assylias.jbloomberg;

import com.bloomberglp.blpapi.Datetime;
import com.bloomberglp.blpapi.Element;
import com.bloomberglp.blpapi.ElementIterator;
import com.bloomberglp.blpapi.Schema;
import java.io.BufferedReader;
import java.io.File;
import java.io.InputStreamReader;
import java.nio.charset.Charset;
import java.time.LocalDate;
import java.time.LocalTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * A utility class that should not be very useful for the users of the API.
 */
final class BloombergUtils {

    private final static Logger logger = LoggerFactory.getLogger(BloombergUtils.class);
    private static volatile boolean isBbcommStarted = false;
    private final static String BBCOMM_PROCESS = "bbcomm.exe";
    private final static String BBCOMM_FOLDER = "C:/blp/API";

    private BloombergUtils() {
    }

    /**
     * Transforms a Bloomberg Element into the most specific Object (for example: Double, Float, Integer, DateTime,
     * String etc.).<br>
     * Complex types are returned in the form of collections ({@code List<Object>} for arrays and
     * {@code Map<String, Object>}
     * for sequences).
     */
    public static Object getSpecificObjectOf(Element field) {
        if (field.datatype() == Schema.Datatype.FLOAT64) {
            //likeliest data type
            return field.getValueAsFloat64();
        } else if (field.datatype() == Schema.Datatype.FLOAT32) {
            return field.getValueAsFloat32();
        } else if (field.datatype() == Schema.Datatype.BOOL) {
            return field.getValueAsBool();
        } else if (field.datatype() == Schema.Datatype.CHAR) {
            return field.getValueAsChar();
        } else if (field.datatype() == Schema.Datatype.INT32) {
            return field.getValueAsInt32();
        } else if (field.datatype() == Schema.Datatype.INT64) {
            return field.getValueAsInt64();
        } else if (field.datatype() == Schema.Datatype.STRING) {
            return field.getValueAsString();
        } else if (field.datatype() == Schema.Datatype.DATE) {
            Datetime dt = field.getValueAsDate();
            return LocalDate.of(dt.year(), dt.month(), dt.dayOfMonth());
        } else if (field.datatype() == Schema.Datatype.TIME) {
            Datetime dt = field.getValueAsDatetime();
            Calendar cal = dt.calendar(); //returns a calendar with TZ = UTC
            return LocalTime.of(cal.get(Calendar.HOUR_OF_DAY), cal.get(Calendar.MINUTE), cal.get(Calendar.SECOND), dt.nanosecond());
        } else if (field.datatype() == Schema.Datatype.DATETIME) {
            Datetime dt = field.getValueAsDatetime();
            Calendar cal = dt.calendar(); //returns a calendar with TZ = UTC
            ZonedDateTime zdt = ZonedDateTime.ofInstant(cal.toInstant(), ZoneId.of("Z"));
            if (!dt.hasParts(Datetime.DATE)) return zdt.toLocalTime();
            else return zdt;
        } else if (field.isArray()) {
            List<Object> list = new ArrayList<>(field.numValues());
            for (int i = 0; i < field.numValues(); i++) {
                list.add(getSpecificObjectOf(field.getValueAsElement(i)));
            }
            return list;
        } else if (field.datatype() == Schema.Datatype.SEQUENCE
                || field.datatype() == Schema.Datatype.CHOICE) { //has to be after array because arrays are sequences...
            ElementIterator it = field.elementIterator();
            Map<String, Object> map = new LinkedHashMap<>(field.numElements(), 1.0f);
            while (it.hasNext()) {
                Element e = it.next();
                map.put(e.name().toString(), getSpecificObjectOf(e));
            }
            return map;
        } else {
            return field.toString(); //always works
        }
    }

    /**
     * Starts the bbcomm process if necessary, which is required to connect to the Bloomberg data feed.<br>
     * This method will block up to one second if it needs to manually start the process. If the process is not
     * started by the end of the timeout, this method will return false but the process might start later on.
     * <p/>
     * @return true if bbcomm was started successfully within one second, false otherwise.
     */
    public static boolean startBloombergProcessIfNecessary() {
{'fraction_non_alphanumeric': 0.11169247197010145, 'fraction_numerical': 0.005339028296849973, 'mean_word_length': 2.8559077809798272, 'pattern_counts': {'":': 0, '<': 25, '<?xml version=': 0, '>': 23, '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': '7056691', 'n_tokens_mistral': 2647, 'n_tokens_neox': 2583, 'n_words': 738}