1 /*
   2  * Copyright (c) 2014, 2016, 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 #ifndef PLATFORM_H
  35 #define PLATFORM_H
  36 
  37 #include "OrderedMap.h"
  38 
  39 #include <stdio.h>
  40 #include <stdlib.h>
  41 #include <memory.h>
  42 #include <string>
  43 #include <map>
  44 #include <list>
  45 #include <vector>
  46 
  47 
  48 #ifdef WIN32
  49 #define WINDOWS
  50 #endif //WIN32
  51 
  52 #ifdef __APPLE__
  53 #define MAC
  54 #define POSIX
  55 #endif //__APPLE__
  56 
  57 
  58 #ifdef __linux
  59 #define LINUX
  60 #endif //__linux
  61 
  62 #ifdef LINUX
  63 #define POSIX
  64 #endif //LINUX
  65 
  66 
  67 
  68 #ifdef WINDOWS
  69 // Define Windows compatibility requirements XP or later
  70 #define WINVER 0x0501
  71 #define _WIN32_WINNT 0x0501
  72 
  73 #include <Windows.h>
  74 #include <tchar.h>
  75 #include <shlobj.h>
  76 #include <direct.h>
  77 #include <process.h>
  78 #include <malloc.h>
  79 
  80 typedef std::wstring TString;
  81 #define StringLength wcslen
  82 
  83 #define TRAILING_PATHSEPARATOR '\\'
  84 #define BAD_TRAILING_PATHSEPARATOR '/'
  85 #define PATH_SEPARATOR ';'
  86 #define BAD_PATH_SEPARATOR ':'
  87 
  88 typedef ULONGLONG TPlatformNumber;
  89 typedef DWORD TProcessID;
  90 
  91 #if defined _DEBUG && !defined DEBUG
  92     #define DEBUG
  93 #endif
  94 
  95 #endif //WINDOWS
  96 
  97 
  98 #ifdef POSIX
  99 #include <errno.h>
 100 #include <unistd.h>
 101 #include <sys/stat.h>
 102 #include <dlfcn.h>
 103 #include <libgen.h>
 104 
 105 #define _T(x) x
 106 
 107 typedef char TCHAR;
 108 typedef std::string TString;
 109 #define StringLength strlen
 110 
 111 typedef unsigned long DWORD;
 112 
 113 #define TRAILING_PATHSEPARATOR '/'
 114 #define BAD_TRAILING_PATHSEPARATOR '\\'
 115 #define PATH_SEPARATOR ':'
 116 #define BAD_PATH_SEPARATOR ';'
 117 #define MAX_PATH 1000
 118 
 119 typedef long TPlatformNumber;
 120 typedef pid_t TProcessID;
 121 
 122 #define HMODULE void*
 123 #endif //POSIX
 124 
 125 
 126 // Config file sections
 127 #define CONFIG_SECTION_APPLICATION                   _T("CONFIG_SECTION_APPLICATION")
 128 #define CONFIG_SECTION_JVMOPTIONS                    _T("CONFIG_SECTION_JVMOPTIONS")
 129 #define CONFIG_SECTION_JVMUSEROPTIONS                _T("CONFIG_SECTION_JVMUSEROPTIONS")
 130 #define CONFIG_SECTION_JVMUSEROVERRIDESOPTIONS       _T("CONFIG_SECTION_JVMUSEROVERRIDESOPTIONS")
 131 #define CONFIG_SECTION_APPCDSJVMOPTIONS              _T("CONFIG_SECTION_APPCDSJVMOPTIONS")
 132 #define CONFIG_SECTION_APPCDSGENERATECACHEJVMOPTIONS _T("CONFIG_SECTION_APPCDSGENERATECACHEJVMOPTIONS")
 133 #define CONFIG_SECTION_ARGOPTIONS                    _T("CONFIG_SECTION_ARGOPTIONS")
 134 
 135 // Config file keys.
 136 #define CONFIG_VERSION            _T("CONFIG_VERSION")
 137 #define CONFIG_MAINJAR_KEY        _T("CONFIG_MAINJAR_KEY")
 138 #define CONFIG_MAINMODULE_KEY     _T("CONFIG_MAINMODULE_KEY")
 139 #define CONFIG_MAINCLASSNAME_KEY  _T("CONFIG_MAINCLASSNAME_KEY")
 140 #define CONFIG_CLASSPATH_KEY      _T("CONFIG_CLASSPATH_KEY")
 141 #define CONFIG_MODULEPATH_KEY     _T("CONFIG_MODULEPATH_KEY")
 142 #define APP_NAME_KEY              _T("APP_NAME_KEY")
 143 #define CONFIG_SPLASH_KEY         _T("CONFIG_SPLASH_KEY")
 144 #define CONFIG_APP_ID_KEY         _T("CONFIG_APP_ID_KEY")
 145 #define CONFIG_APP_MEMORY         _T("CONFIG_APP_MEMORY")
 146 
 147 #define JVM_RUNTIME_KEY           _T("JVM_RUNTIME_KEY")
 148 #define PACKAGER_APP_DATA_DIR     _T("CONFIG_APP_IDENTIFIER")
 149 
 150 
 151 
 152 typedef void* Module;
 153 typedef void* Procedure;
 154 
 155 
 156 template <typename ObjectType, typename ValueType, ValueType (ObjectType::*getter)(void), void (ObjectType::*setter)(ValueType)>
 157 class Property {
 158 private:
 159     ObjectType* FObject;
 160 
 161 public:
 162     Property() {
 163         FObject = NULL;
 164     }
 165 
 166     void SetInstance(ObjectType* Value) {
 167         FObject = Value;
 168     }
 169 
 170     // To set the value using the set method.
 171     ValueType operator =(const ValueType& Value) {
 172         assert(FObject != NULL);
 173         (FObject->*setter)(Value);
 174         return Value;
 175     }
 176 
 177     // The Property class is treated as the internal type.
 178     operator ValueType() {
 179         assert(FObject != NULL);
 180         return (FObject->*getter)();
 181     }
 182 };
 183 
 184 template <typename ObjectType, typename ValueType, ValueType (ObjectType::*getter)(void)>
 185 class ReadProperty {
 186 private:
 187     ObjectType* FObject;
 188 
 189 public:
 190     ReadProperty() {
 191         FObject = NULL;
 192     }
 193 
 194     void SetInstance(ObjectType* Value) {
 195         FObject = Value;
 196     }
 197 
 198     // The Property class is treated as the internal type.
 199     operator ValueType() {
 200         assert(FObject != NULL);
 201         return (FObject->*getter)();
 202     }
 203 };
 204 
 205 template <typename ObjectType, typename ValueType, void (ObjectType::*setter)(ValueType)>
 206 class WriteProperty {
 207 private:
 208     ObjectType* FObject;
 209 
 210 public:
 211     WriteProperty() {
 212         FObject = NULL;
 213     }
 214 
 215     void SetInstance(ObjectType* Value) {
 216         FObject = Value;
 217     }
 218 
 219     // To set the value using the set method.
 220     ValueType operator =(const ValueType& Value) {
 221         assert(FObject != NULL);
 222         (FObject->*setter)(Value);
 223         return Value;
 224     }
 225 };
 226 
 227 template <typename ValueType, ValueType (*getter)(void), void (*setter)(ValueType)>
 228 class StaticProperty {
 229 public:
 230     StaticProperty() {
 231     }
 232 
 233     // To set the value using the set method.
 234     ValueType operator =(const ValueType& Value) {
 235         (*getter)(Value);
 236         return Value;
 237     }
 238 
 239     // The Property class is treated as the internal type which is the getter.
 240     operator ValueType() {
 241         return (*setter)();
 242     }
 243 };
 244 
 245 template <typename ValueType, ValueType (*getter)(void)>
 246 class StaticReadProperty {
 247 public:
 248     StaticReadProperty() {
 249     }
 250 
 251     // The Property class is treated as the internal type which is the getter.
 252     operator ValueType() {
 253         return (*getter)();
 254     }
 255 };
 256 
 257 template <typename ValueType, void (*setter)(ValueType)>
 258 class StaticWriteProperty {
 259 public:
 260     StaticWriteProperty() {
 261     }
 262 
 263     // To set the value using the set method.
 264     ValueType operator =(const ValueType& Value) {
 265         (*setter)(Value);
 266         return Value;
 267     }
 268 };
 269 
 270 
 271 class Process {
 272 protected:
 273     std::list<TString> FOutput;
 274 
 275 public:
 276     Process() {
 277         Output.SetInstance(this);
 278         Input.SetInstance(this);
 279     }
 280 
 281     virtual ~Process() {}
 282 
 283     virtual bool IsRunning() = 0;
 284     virtual bool Terminate() = 0;
 285     virtual bool Execute(const TString Application, const std::vector<TString> Arguments,
 286         bool AWait = false) = 0;
 287     virtual bool Wait() = 0;
 288     virtual TProcessID GetProcessID() = 0;
 289 
 290     virtual std::list<TString> GetOutput() { return FOutput; }
 291     virtual void SetInput(TString Value) = 0;
 292 
 293     ReadProperty<Process, std::list<TString>, &Process::GetOutput> Output;
 294     WriteProperty<Process, TString, &Process::SetInput> Input;
 295 };
 296 
 297 
 298 template <typename T>
 299 class AutoFreePtr {
 300 private:
 301     T* FObject;
 302 
 303 public:
 304     AutoFreePtr() {
 305         FObject = NULL;
 306     }
 307 
 308     AutoFreePtr(T* Value) {
 309         FObject = Value;
 310     }
 311 
 312     ~AutoFreePtr() {
 313         if (FObject != NULL) {
 314             delete FObject;
 315         }
 316     }
 317 
 318     operator T* () const {
 319         return FObject;
 320     }
 321 
 322     T& operator* () const {
 323         return *FObject;
 324     }
 325 
 326     T* operator->() const {
 327         return FObject;
 328     }
 329 
 330     T** operator&() {
 331         return &FObject;
 332     }
 333 
 334     T* operator=(const T * rhs) {
 335         FObject = rhs;
 336         return FObject;
 337     }
 338 };
 339 
 340 
 341 class IPropertyContainer {
 342 public:
 343     IPropertyContainer(void) {}
 344     virtual ~IPropertyContainer(void) {}
 345 
 346     virtual bool GetValue(const TString Key, TString& Value) = 0;
 347     virtual size_t GetCount() = 0;
 348 };
 349 
 350 class ISectionalPropertyContainer {
 351 public:
 352     ISectionalPropertyContainer(void) {}
 353     virtual ~ISectionalPropertyContainer(void) {}
 354 
 355     virtual bool GetValue(const TString SectionName, const TString Key, TString& Value) = 0;
 356     virtual bool ContainsSection(const TString SectionName) = 0;
 357     virtual bool GetSection(const TString SectionName, OrderedMap<TString, TString> &Data) = 0;
 358 };
 359 
 360 class Environment {
 361 private:
 362     Environment() {
 363     }
 364 
 365 public:
 366     static TString GetNewLine() {
 367 #ifdef WINDOWS
 368         return _T("\r\n");
 369 #endif //WINDOWS
 370 #ifdef POSIX
 371         return _T("\n");
 372 #endif //POSIX
 373     }
 374 
 375     static StaticReadProperty<TString, &Environment::GetNewLine> NewLine;
 376 };
 377 
 378 
 379 enum DebugState {dsNone, dsNative, dsJava};
 380 enum MessageResponse {mrOK, mrCancel};
 381 enum AppCDSState {cdsUninitialized, cdsDisabled, cdsEnabled, cdsAuto, cdsGenCache};
 382 
 383 class Platform {
 384 private:
 385     AppCDSState FAppCDSState;
 386 
 387 protected:
 388     Platform(void) {
 389         FAppCDSState = cdsUninitialized;
 390     }
 391 
 392 public:
 393     AppCDSState GetAppCDSState() { return FAppCDSState; }
 394     void SetAppCDSState(AppCDSState Value) { FAppCDSState = Value; }
 395 
 396     static Platform& GetInstance();
 397 
 398     virtual ~Platform(void) {}
 399 
 400 public:
 401     virtual void ShowMessage(TString title, TString description) = 0;
 402     virtual void ShowMessage(TString description) = 0;
 403     virtual MessageResponse ShowResponseMessage(TString title, TString description) = 0;
 404 //    virtual MessageResponse ShowResponseMessage(TString description) = 0;
 405 
 406     virtual void SetCurrentDirectory(TString Value) = 0;
 407 
 408     // Caller must free result using delete[].
 409     virtual TCHAR* ConvertStringToFileSystemString(TCHAR* Source, bool &release) = 0;
 410 
 411     // Caller must free result using delete[].
 412     virtual TCHAR* ConvertFileSystemStringToString(TCHAR* Source, bool &release) = 0;
 413 
 414     // Returns:
 415     // Windows=C:\Users\<username>\AppData\Local\<app.identifier>\packager\jvmuserargs.cfg
 416     // Linux=~/.local/<app.identifier>/packager/jvmuserargs.cfg
 417     // Mac=~/Library/Application Support/<app.identifier>/packager/jvmuserargs.cfg
 418     virtual TString GetAppDataDirectory() = 0;
 419 
 420     virtual TString GetPackageAppDirectory() = 0;
 421     virtual TString GetPackageLauncherDirectory() = 0;
 422     virtual TString GetAppName() = 0;
 423 
 424     virtual TString GetConfigFileName() = 0;
 425 
 426     virtual TString GetBundledJVMLibraryFileName(TString RuntimePath) = 0;
 427     virtual TString GetSystemJVMLibraryFileName() = 0;
 428     virtual TString GetSystemJRE() = 0;
 429 
 430     // Caller must free result.
 431     virtual ISectionalPropertyContainer* GetConfigFile(TString FileName) = 0;
 432 
 433     virtual TString GetModuleFileName() = 0;
 434     virtual TString GetPackageRootDirectory() = 0;
 435 
 436     virtual Module LoadLibrary(TString FileName) = 0;
 437     virtual void FreeLibrary(Module Module) = 0;
 438     virtual Procedure GetProcAddress(Module Module, std::string MethodName) = 0;
 439     virtual std::vector<TString> GetLibraryImports(const TString FileName) = 0;
 440     virtual std::vector<TString> FilterOutRuntimeDependenciesForPlatform(std::vector<TString> Imports) = 0;
 441 
 442     // Caller must free result.
 443     virtual Process* CreateProcess() = 0;
 444 
 445     virtual bool IsMainThread() = 0;
 446 
 447     // Returns megabytes.
 448     virtual TPlatformNumber GetMemorySize() = 0;
 449 
 450     virtual std::map<TString, TString> GetKeys() = 0;
 451 
 452     virtual std::list<TString> LoadFromFile(TString FileName) = 0;
 453     virtual void SaveToFile(TString FileName, std::list<TString> Contents, bool ownerOnly) = 0;
 454 
 455 #ifdef DEBUG
 456     virtual DebugState GetDebugState() = 0;
 457     virtual int GetProcessID() = 0;
 458     virtual bool IsNativeDebuggerPresent() = 0;
 459 #endif //DEBUG
 460 };
 461 
 462 
 463 class Library {
 464 private:
 465     std::vector<TString> *FDependentLibraryNames;
 466     std::vector<Library*> *FDependenciesLibraries;
 467     Module FModule;
 468 
 469     void Initialize();
 470     void InitializeDependencies();
 471     void LoadDependencies();
 472     void UnloadDependencies();
 473 
 474 protected:
 475     void* GetProcAddress(std::string MethodName);
 476 
 477 public:
 478     Library();
 479     Library(const TString &FileName);
 480     ~Library();
 481 
 482     bool Load(const TString &FileName);
 483     bool Unload();
 484 
 485     void AddDependency(const TString &FileName);
 486     void AddDependencies(const std::vector<TString> &Dependencies);
 487 };
 488 
 489 
 490 class Exception: public std::exception {
 491 private:
 492     TString FMessage;
 493 
 494 protected:
 495     void SetMessage(const TString Message) {
 496         FMessage = Message;
 497     }
 498 
 499 public:
 500     explicit Exception() : exception() {}
 501     explicit Exception(const TString Message) : exception() {
 502         SetMessage(Message);
 503     }
 504     virtual ~Exception() throw() {}
 505 
 506     TString GetMessage() { return FMessage; }
 507 };
 508 
 509 class FileNotFoundException: public Exception {
 510 public:
 511     explicit FileNotFoundException(const TString Message) : Exception(Message) {}
 512 };
 513 
 514 #endif //PLATFORM_H