/*
 * Copyright 2017, Google Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *
 *     * Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above
 * copyright notice, this list of conditions and the following disclaimer
 * in the documentation and/or other materials provided with the
 * distribution.
 *     * Neither the name of Google Inc. nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
package com.google.api.gax.core;

import java.util.Properties;

/**
 * Provides meta-data properties stored in a properties file.
 */
public class PropertiesProvider {

  private static final Properties gaxProperties = new Properties();
  private static final String DEFAULT_VERSION = "";

  /**
   * Returns the current version of GAX
   */
  public static String getGaxVersion() {
    String gaxVersion = loadGaxProperty("version");
    return gaxVersion != null ? gaxVersion : DEFAULT_VERSION;
  }

  /**
   * Returns the current version of gRPC
   */
  public static String getGrpcVersion() {
    String grpcVersion = loadGaxProperty("grpc_version");
    return grpcVersion != null ? grpcVersion : DEFAULT_VERSION;
  }

  /**
   * Utility method of retrieving the property value of the given key from a property file in the
   * package.
   *
   * @param loadedClass The class used to get the resource path
   * @param propertyFilePath The relative file path to the property file
   * @param key Key string of the property
   */
  public static String loadProperty(Class<?> loadedClass, String propertyFilePath, String key) {
    try {
      Properties properties = new Properties();
      properties.load(loadedClass.getResourceAsStream(propertyFilePath));
      return properties.getProperty(key);
    } catch (Exception e) {
      e.printStackTrace(System.err);
    }
    return null;
  }

  private static String loadGaxProperty(String key) {
    try {
      if (gaxProperties.isEmpty()) {
        gaxProperties.load(
            PropertiesProvider.class.getResourceAsStream("/com/google/api/gax/gax.properties"));
      }
      return gaxProperties.getProperty(key);
    } catch (Exception e) {
      e.printStackTrace(System.err);
    }
    return null;
  }
}

@@ -1587,16 +1587,44 @@
 .core;%0A%0A
+import java.io.InputStream;%0A
 import j
@@ -1818,16 +1818,104 @@
 ties();%0A
+  private static final String GAX_PROPERTY_FILE = %22/com/google/api/gax/gax.properties%22;%0A
   privat
@@ -2805,24 +2805,142 @@
 %7B%0A    try %7B%0A
+      InputStream inputStream = loadedClass.getResourceAsStream(propertyFilePath);%0A      if (inputStream != null) %7B%0A  
       Proper
@@ -2981,16 +2981,18 @@
 ;%0A      
+  
 properti
@@ -3003,60 +3003,24 @@
 oad(
-loadedClass.getResourceAsStream(propertyFilePath)
+inputStream
 );%0A
+  
     
@@ -3049,32 +3049,118 @@
 tProperty(key);%0A
+      %7D else %7B%0A        printMissingProperties(loadedClass, propertyFilePath);%0A      %7D%0A
     %7D catch (Exc
@@ -3349,39 +3349,33 @@
     
-gaxProperties.load(%0A           
+InputStream inputStream =
  Pro
@@ -3420,187 +3420,643 @@
 eam(
-%22/com/google/api/gax/gax.properties%22));%0A      %7D%0A      return gaxProperties.getProperty(key);%0A    %7D catch (Exception e) %7B%0A      e.printStackTrace(System.err);%0A    %7D%0A    return null
+GAX_PROPERTY_FILE);%0A        if (inputStream != null) %7B%0A          gaxProperties.load(inputStream);%0A        %7D else %7B%0A          printMissingProperties(PropertiesProvider.class, GAX_PROPERTY_FILE);%0A          return null;%0A        %7D%0A      %7D%0A      return gaxProperties.getProperty(key);%0A    %7D catch (Exception e) %7B%0A      e.printStackTrace(System.err);%0A    %7D%0A    return null;%0A  %7D%0A%0A  private static void printMissingProperties(Class%3C?%3E loadedClass, String propertyFilePath) %7B%0A    System.err.format(%0A        %22Warning: Failed to open properties resource at '%25s' of the given class '%25s'%5Cn%22,%0A        propertyFilePath,%0A        loadedClass.getName())
 ;%0A  

Print warning instead of stacktrace while failed at reading properties. (#278)