1 /*
   2  * Copyright (c) 2014, 2015, 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_MAINCLASSNAME_KEY  _T("CONFIG_MAINCLASSNAME_KEY")
 139 #define CONFIG_CLASSPATH_KEY      _T("CONFIG_CLASSPATH_KEY")
 140 #define CONFIG_MODULEPATH_KEY     _T("CONFIG_MODULEPATH_KEY")
 141 #define APP_NAME_KEY              _T("APP_NAME_KEY")
 142 #define CONFIG_SPLASH_KEY         _T("CONFIG_SPLASH_KEY")
 143 #define CONFIG_APP_ID_KEY         _T("CONFIG_APP_ID_KEY")
 144 #define CONFIG_APP_MEMORY         _T("CONFIG_APP_MEMORY")
 145 
 146 #define JVM_RUNTIME_KEY           _T("JVM_RUNTIME_KEY")
 147 #define PACKAGER_APP_DATA_DIR     _T("CONFIG_APP_IDENTIFIER")
 148 
 149 
 150 
 151 typedef void* Module;
 152 typedef void* Procedure;
 153 
 154 
 155 template <typename ObjectType, typename ValueType, ValueType (ObjectType::*getter)(void), void (ObjectType::*setter)(ValueType)>
 156 class Property {
 157 private:
 158     ObjectType* FObject;
 159 
 160 public:
 161     Property() {
 162         FObject = NULL;
 163     }
 164 
 165     void SetInstance(ObjectType* Value) {
 166         FObject = Value;
 167     }
 168 
 169     // To set the value using the set method.
 170     ValueType operator =(const ValueType& Value) {
 171         assert(FObject != NULL);
 172         (FObject->*setter)(Value);
 173         return Value;
 174     }
 175 
 176     // The Property class is treated as the internal type.
 177     operator ValueType() {
 178         assert(FObject != NULL);
 179         return (FObject->*getter)();
 180     }
 181 };
 182 
 183 template <typename ObjectType, typename ValueType, ValueType (ObjectType::*getter)(void)>
 184 class ReadProperty {
 185 private:
 186     ObjectType* FObject;
 187 
 188 public:
 189     ReadProperty() {
 190         FObject = NULL;
 191     }
 192 
 193     void SetInstance(ObjectType* Value) {
 194         FObject = Value;
 195     }
 196 
 197     // The Property class is treated as the internal type.
 198     operator ValueType() {
 199         assert(FObject != NULL);
 200         return (FObject->*getter)();
 201     }
 202 };
 203 
 204 template <typename ObjectType, typename ValueType, void (ObjectType::*setter)(ValueType)>
 205 class WriteProperty {
 206 private:
 207     ObjectType* FObject;
 208 
 209 public:
 210     WriteProperty() {
 211         FObject = NULL;
 212     }
 213 
 214     void SetInstance(ObjectType* Value) {
 215         FObject = Value;
 216     }
 217 
 218     // To set the value using the set method.
 219     ValueType operator =(const ValueType& Value) {
 220         assert(FObject != NULL);
 221         (FObject->*setter)(Value);
 222         return Value;
 223     }
 224 };
 225 
 226 template <typename ValueType, ValueType (*getter)(void), void (*setter)(ValueType)>
 227 class StaticProperty {
 228 public:
 229     StaticProperty() {
 230     }
 231 
 232     // To set the value using the set method.
 233     ValueType operator =(const ValueType& Value) {
 234         (*getter)(Value);
 235         return Value;
 236     }
 237 
 238     // The Property class is treated as the internal type which is the getter.
 239     operator ValueType() {
 240         return (*setter)();
 241     }
 242 };
 243 
 244 template <typename ValueType, ValueType (*getter)(void)>
 245 class StaticReadProperty {
 246 public:
 247     StaticReadProperty() {
 248     }
 249 
 250     // The Property class is treated as the internal type which is the getter.
 251     operator ValueType() {
 252         return (*getter)();
 253     }
 254 };
 255 
 256 template <typename ValueType, void (*setter)(ValueType)>
 257 class StaticWriteProperty {
 258 public:
 259     StaticWriteProperty() {
 260     }
 261 
 262     // To set the value using the set method.
 263     ValueType operator =(const ValueType& Value) {
 264         (*setter)(Value);
 265         return Value;
 266     }
 267 };
 268 
 269 
 270 class Process {
 271 protected:
 272     std::list<TString> FOutput;
 273 
 274 public:
 275     Process() {
 276         Output.SetInstance(this);
 277         Input.SetInstance(this);
 278     }
 279 
 280     virtual ~Process() {}
 281 
 282     virtual bool IsRunning() = 0;
 283     virtual bool Terminate() = 0;
 284     virtual bool Execute(const TString Application, const std::vector<TString> Arguments,
 285         bool AWait = false) = 0;
 286     virtual bool Wait() = 0;
 287     virtual TProcessID GetProcessID() = 0;
 288 
 289     virtual std::list<TString> GetOutput() { return FOutput; }
 290     virtual void SetInput(TString Value) = 0;
 291 
 292     ReadProperty<Process, std::list<TString>, &Process::GetOutput> Output;
 293     WriteProperty<Process, TString, &Process::SetInput> Input;
 294 };
 295 
 296 
 297 template <typename T>
 298 class AutoFreePtr {
 299 private:
 300     T* FObject;
 301 
 302 public:
 303     AutoFreePtr() {
 304         FObject = NULL;
 305     }
 306 
 307     AutoFreePtr(T* Value) {
 308         FObject = Value;
 309     }
 310 
 311     ~AutoFreePtr() {
 312         if (FObject != NULL) {
 313             delete FObject;
 314         }
 315     }
 316 
 317     operator T* () const {
 318         return FObject;
 319     }
 320 
 321     T& operator* () const {
 322         return *FObject;
 323     }
 324 
 325     T* operator->() const {
 326         return FObject;
 327     }
 328 
 329     T** operator&() {
 330         return &FObject;
 331     }
 332 
 333     T* operator=(const T * rhs) {
 334         FObject = rhs;
 335         return FObject;
 336     }
 337 };
 338 
 339 
 340 class IPropertyContainer {
 341 public:
 342     IPropertyContainer(void) {}
 343     virtual ~IPropertyContainer(void) {}
 344 
 345     virtual bool GetValue(const TString Key, TString& Value) = 0;
 346     virtual size_t GetCount() = 0;
 347 };
 348 
 349 class ISectionalPropertyContainer {
 350 public:
 351     ISectionalPropertyContainer(void) {}
 352     virtual ~ISectionalPropertyContainer(void) {}
 353 
 354     virtual bool GetValue(const TString SectionName, const TString Key, TString& Value) = 0;
 355     virtual bool ContainsSection(const TString SectionName) = 0;
 356     virtual bool GetSection(const TString SectionName, OrderedMap<TString, TString> &Data) = 0;
 357 };
 358 
 359 class Environment {
 360 private:
 361     Environment() {
 362     }
 363 
 364 public:
 365     static TString GetNewLine() {
 366 #ifdef WINDOWS
 367         return _T("\r\n");
 368 #endif //WINDOWS
 369 #ifdef POSIX
 370         return _T("\n");
 371 #endif //POSIX
 372     }
 373 
 374     static StaticReadProperty<TString, &Environment::GetNewLine> NewLine;
 375 };
 376 
 377 
 378 enum DebugState {dsNone, dsNative, dsJava};
 379 enum MessageResponse {mrOK, mrCancel};
 380 enum AppCDSState {cdsUninitialized, cdsDisabled, cdsEnabled, cdsAuto, cdsGenCache};
 381 
 382 class Platform {
 383 private:
 384     AppCDSState FAppCDSState;
 385 
 386 protected:
 387     Platform(void) {
 388         FAppCDSState = cdsUninitialized;
 389     }
 390 
 391 public:
 392     AppCDSState GetAppCDSState() { return FAppCDSState; }
 393     void SetAppCDSState(AppCDSState Value) { FAppCDSState = Value; }
 394 
 395     static Platform& GetInstance();
 396 
 397     virtual ~Platform(void) {}
 398 
 399 public:
 400     virtual void ShowMessage(TString title, TString description) = 0;
 401     virtual void ShowMessage(TString description) = 0;
 402     virtual MessageResponse ShowResponseMessage(TString title, TString description) = 0;
 403 //    virtual MessageResponse ShowResponseMessage(TString description) = 0;
 404 
 405     virtual void SetCurrentDirectory(TString Value) = 0;
 406 
 407     // Caller must free result using delete[].
 408     virtual TCHAR* ConvertStringToFileSystemString(TCHAR* Source, bool &release) = 0;
 409 
 410     // Caller must free result using delete[].
 411     virtual TCHAR* ConvertFileSystemStringToString(TCHAR* Source, bool &release) = 0;
 412 
 413     // Returns:
 414     // Windows=C:\Users\<username>\AppData\Local\<app.identifier>\packager\jvmuserargs.cfg
 415     // Linux=~/.local/<app.identifier>/packager/jvmuserargs.cfg
 416     // Mac=~/Library/Application Support/<app.identifier>/packager/jvmuserargs.cfg
 417     virtual TString GetAppDataDirectory() = 0;
 418 
 419     virtual TString GetPackageAppDirectory() = 0;
 420     virtual TString GetPackageLauncherDirectory() = 0;
 421     virtual TString GetAppName() = 0;
 422 
 423     virtual TString GetConfigFileName() = 0;
 424 
 425     virtual TString GetBundledJVMLibraryFileName(TString RuntimePath) = 0;
 426     virtual TString GetSystemJVMLibraryFileName() = 0;
 427     virtual TString GetSystemJRE() = 0;
 428 
 429     // Caller must free result.
 430     virtual ISectionalPropertyContainer* GetConfigFile(TString FileName) = 0;
 431 
 432     virtual TString GetModuleFileName() = 0;
 433     virtual TString GetPackageRootDirectory() = 0;
 434 
 435     virtual Module LoadLibrary(TString FileName) = 0;
 436     virtual void FreeLibrary(Module Module) = 0;
 437     virtual Procedure GetProcAddress(Module Module, std::string MethodName) = 0;
 438     virtual std::vector<TString> GetLibraryImports(const TString FileName) = 0;
 439     virtual std::vector<TString> FilterOutRuntimeDependenciesForPlatform(std::vector<TString> Imports) = 0;
 440 
 441     // Caller must free result.
 442     virtual Process* CreateProcess() = 0;
 443 
 444     virtual bool IsMainThread() = 0;
 445 
 446     // Returns megabytes.
 447     virtual TPlatformNumber GetMemorySize() = 0;
 448 
 449     virtual std::map<TString, TString> GetKeys() = 0;
 450 
 451     virtual std::list<TString> LoadFromFile(TString FileName) = 0;
 452     virtual void SaveToFile(TString FileName, std::list<TString> Contents, bool ownerOnly) = 0;
 453 
 454 #ifdef DEBUG
 455     virtual DebugState GetDebugState() = 0;
 456     virtual int GetProcessID() = 0;
 457     virtual bool IsNativeDebuggerPresent() = 0;
 458 #endif //DEBUG
 459 };
 460 
 461 
 462 class Library {
 463 private:
 464     std::vector<TString> *FDependentLibraryNames;
 465     std::vector<Library*> *FDependenciesLibraries;
 466     Module FModule;
 467 
 468     void Initialize();
 469     void InitializeDependencies();
 470     void LoadDependencies();
 471     void UnloadDependencies();
 472 
 473 protected:
 474     void* GetProcAddress(std::string MethodName);
 475 
 476 public:
 477     Library();
 478     Library(const TString &FileName);
 479     ~Library();
 480 
 481     bool Load(const TString &FileName);
 482     bool Unload();
 483 
 484     void AddDependency(const TString &FileName);
 485     void AddDependencies(const std::vector<TString> &Dependencies);
 486 };
 487 
 488 
 489 class Exception: public std::exception {
 490 private:
 491     TString FMessage;
 492 
 493 protected:
 494     void SetMessage(const TString Message) {
 495         FMessage = Message;
 496     }
 497 
 498 public:
 499     explicit Exception() : exception() {}
 500     explicit Exception(const TString Message) : exception() {
 501         SetMessage(Message);
 502     }
 503     virtual ~Exception() throw() {}
 504 
 505     TString GetMessage() { return FMessage; }
 506 };
 507 
 508 class FileNotFoundException: public Exception {
 509 public:
 510     explicit FileNotFoundException(const TString Message) : Exception(Message) {}
 511 };
 512 
 513 #endif //PLATFORM_H