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