1 /*
   2  * Copyright (c) 2014, Oracle and/or its affiliates.
   3  * All rights reserved. Use is subject to license terms.
   4  *
   5  * This file is available and licensed under the following license:
   6  *
   7  * Redistribution and use in source and binary forms, with or without
   8  * modification, are permitted provided that the following conditions
   9  * are met:
  10  *
  11  *  - Redistributions of source code must retain the above copyright
  12  *    notice, this list of conditions and the following disclaimer.
  13  *  - Redistributions in binary form must reproduce the above copyright
  14  *    notice, this list of conditions and the following disclaimer in
  15  *    the documentation and/or other materials provided with the distribution.
  16  *  - Neither the name of Oracle Corporation nor the names of its
  17  *    contributors may be used to endorse or promote products derived
  18  *    from this software without specific prior written permission.
  19  *
  20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  21  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  22  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  23  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  24  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  25  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  26  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  27  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  28  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  29  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  30  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  31  */
  32 
  33 
  34 #include "Platform.h"
  35 #include "Package.h"
  36 #include "PlatformString.h"
  37 #include "PropertyFile.h"
  38 #include "Lock.h"
  39 #include "Java.h"
  40 
  41 #include "jni.h"
  42 
  43 
  44 class UserJVMArgsExports {
  45 private:
  46     // This is not a class to create an instance of.
  47     UserJVMArgsExports();
  48 
  49     static jobjectArray MapKeysToJObjectArray(JNIEnv *env, OrderedMap<TString, TString> map) {
  50         std::vector<TString> keys = map.GetKeys();
  51         JavaStringArray result(env, keys.size());
  52 
  53         for (unsigned int index = 0; index < keys.size(); index++) {
  54             jstring item = PlatformString(keys[index]).toJString(env);
  55             result.SetValue(index, item);
  56         }
  57 
  58 //        JavaStringArray result(env, map.Count());
  59 //
  60 //        for (map::  iterator = map.begin(); iterator != map.end(); iterator++) {
  61 //            jstring item = PlatformString(keys[index]).toJString(env);
  62 //            result.SetValue(index, item);
  63 //        }
  64 
  65         return result.GetData();
  66     }
  67 
  68 public:
  69     static jstring _getUserJvmOptionDefaultValue(JNIEnv *env, jstring option) {
  70         if (env == NULL || option == NULL)
  71             return NULL;
  72 
  73         jstring result = NULL;
  74 
  75         Package& package = Package::GetInstance();
  76         OrderedMap<TString, TString> defaultuserargs = package.GetDefaultJVMUserArgs();
  77         TString loption = PlatformString(env, option).toString();
  78 
  79         try {
  80             TString temp;
  81             defaultuserargs.GetValue(loption, temp);
  82             PlatformString value = temp;
  83             result = value.toJString(env);
  84         }
  85         catch (const JavaException&) {
  86         }
  87 
  88         return result;
  89     }
  90 
  91     static jobjectArray _getUserJvmOptionDefaultKeys(JNIEnv *env) {
  92         if (env == NULL)
  93             return NULL;
  94 
  95         jobjectArray result = NULL;
  96 
  97         Package& package = Package::GetInstance();
  98 
  99         try {
 100             result = MapKeysToJObjectArray(env, package.GetDefaultJVMUserArgs());
 101         }
 102         catch (const JavaException&) {
 103         }
 104 
 105         return result;
 106     }
 107 
 108     static jstring _getUserJvmOptionValue(JNIEnv *env, jstring option) {
 109         if (env == NULL || option == NULL)
 110             return NULL;
 111 
 112         jstring result = NULL;
 113 
 114         Package& package = Package::GetInstance();
 115         OrderedMap<TString, TString> userargs = package.GetJVMUserArgs();
 116 
 117         try {
 118             TString loption = PlatformString(env, option).toString();
 119             TString temp;
 120             userargs.GetValue(loption, temp);
 121             PlatformString value = temp;
 122             result = value.toJString(env);
 123         }
 124         catch (const JavaException&) {
 125         }
 126 
 127         return result;
 128     }
 129 
 130     static void _setUserJvmKeysAndValues(JNIEnv *env, jobjectArray options, jobjectArray values) {
 131         if (env == NULL || options == NULL || values == NULL)
 132             return;
 133 
 134         Package& package = Package::GetInstance();
 135         OrderedMap<TString, TString> newMap;
 136 
 137         try {
 138             JavaStringArray loptions(env, options);
 139             JavaStringArray lvalues(env, values);
 140 
 141             for (unsigned int index = 0; index < loptions.Count(); index++) {
 142                 TString name = PlatformString(env, loptions.GetValue(index)).toString();
 143                 TString value = PlatformString(env, lvalues.GetValue(index)).toString();
 144                 newMap.Append(name, value);
 145             }
 146         }
 147         catch (const JavaException&) {
 148             return;
 149         }
 150 
 151         package.SetJVMUserArgOverrides(newMap);
 152     }
 153 
 154     static jobjectArray _getUserJvmOptionKeys(JNIEnv *env) {
 155         if (env == NULL)
 156             return NULL;
 157 
 158         jobjectArray result = NULL;
 159 
 160         Package& package = Package::GetInstance();
 161 
 162         try {
 163             result = MapKeysToJObjectArray(env, package.GetJVMUserArgs());
 164         }
 165         catch (const JavaException&) {
 166         }
 167 
 168         return result;
 169     }
 170 };
 171 
 172 
 173 extern "C" {
 174     JNIEXPORT jstring JNICALL Java_jdk_packager_services_userjvmoptions_LauncherUserJvmOptions__1getUserJvmOptionDefaultValue(JNIEnv *env, jclass klass, jstring option) {
 175         return UserJVMArgsExports::_getUserJvmOptionDefaultValue(env, option);
 176     }
 177 
 178     JNIEXPORT jobjectArray JNICALL Java_jdk_packager_services_userjvmoptions_LauncherUserJvmOptions__1getUserJvmOptionDefaultKeys(JNIEnv *env, jclass klass) {
 179         return UserJVMArgsExports::_getUserJvmOptionDefaultKeys(env);
 180     }
 181 
 182     JNIEXPORT jstring JNICALL Java_jdk_packager_services_userjvmoptions_LauncherUserJvmOptions__1getUserJvmOptionValue(JNIEnv *env, jclass klass, jstring option) {
 183         return UserJVMArgsExports::_getUserJvmOptionValue(env, option);
 184     }
 185 
 186     JNIEXPORT void JNICALL Java_jdk_packager_services_userjvmoptions_LauncherUserJvmOptions__1setUserJvmKeysAndValues(JNIEnv *env, jclass klass, jobjectArray options, jobjectArray values) {
 187         UserJVMArgsExports::_setUserJvmKeysAndValues(env, options, values);
 188     }
 189 
 190     JNIEXPORT jobjectArray JNICALL Java_jdk_packager_services_userjvmoptions_LauncherUserJvmOptions__1getUserJvmOptionKeys(JNIEnv *env, jclass klass) {
 191         return UserJVMArgsExports::_getUserJvmOptionKeys(env);
 192     }
 193 }
 194 
 195 #ifdef DEBUG
 196 // Build with debug info. Create a class:
 197 //
 198 // package com;
 199 //
 200 // class DebugExports {
 201 //   static {
 202 //      System.loadLibrary("packager");
 203 //   }
 204 //
 205 //   public static native boolean isdebugged();
 206 //
 207 //   public static native int getpid();
 208 // }
 209 //
 210 // Use the following in Java in the main or somewhere else:
 211 //
 212 // import com.DebugExports;
 213 // import java.util.Arrays;
 214 //
 215 // if (Arrays.asList(args).contains("-debug")) {
 216 //   System.out.println("pid=" + getpid());
 217 //
 218 //   while (true) {
 219 //     if (isdebugged() == true) {
 220 //       break;
 221 //     }
 222 //   }
 223 // }
 224 //
 225 // The call to isdebugger() will wait until a native debugger is attached. The process
 226 // identifier (pid) will be printed to the console for you to attach your debugger to.
 227 extern "C" {
 228     JNIEXPORT jboolean JNICALL Java_com_DebugExports_isdebugged(JNIEnv *env, jclass klass) {
 229         jboolean result = false;
 230         Package& package = Package::GetInstance();
 231 
 232         if (package.Debugging() == dsNative) {
 233             Platform& platform = Platform::GetInstance();
 234             result = platform.GetDebugState() != dsNone;
 235         }
 236 
 237         return result;
 238     }
 239 
 240     JNIEXPORT jint JNICALL Java_com_DebugExports_getpid(JNIEnv *env, jclass klass) {
 241         Platform& platform = Platform::GetInstance();
 242         return platform.GetProcessID();
 243     }
 244 }
 245 #endif //DEBUG